package com.rookie.tool.module.util.io;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.rookie.tool.module.util.lexicon.AnalyserUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * 常用的IO集操作
 *
 * @author rookie
 */
public class CommonIoUtils {

    /**
     * 默认缓存大小
     */
    private static int bufferSize = IoUtil.DEFAULT_BUFFER_SIZE;

    /**
     * 最优线程数
     */
    private static int threadNum = Runtime.getRuntime().availableProcessors() * 2;

    /**
     * 文件复制，将一个文件的内容复制到另外一个文件当中，常用于二进制文件
     *
     * @param from 主文件本地路径+文件名
     * @param to   复制目标文件本地路径+文件名 如果不存在则创建
     */
    public static boolean copyFile(String from, String to) {
        BufferedInputStream in = FileUtil.getInputStream(from);
        int bufferSize = switchInputStreamBufferSize(in);
        BufferedOutputStream out = FileUtil.getOutputStream(to);
        long copySize = IoUtil.copy(in, out, bufferSize);
        return copySize > 0;
    }


    /**
     * 文件复制，将一个文件的内容复制到另外一个文件当中，常用于字符文件
     *
     * @param from    主文件本地路径+文件名
     * @param to      复制目标文件本地路径+文件名 如果不存在则创建
     * @param charset 字符类型 例：StandardCharsets.UTF_8
     */
    public static boolean copyStringFile(String from, String to, Charset charset) {
        BufferedReader reader = FileUtil.getReader(from, charset);
        BufferedWriter writer = FileUtil.getWriter(to, charset, false);
        long copySize = IoUtil.copy(reader, writer, bufferSize);
        return copySize > 0;
    }

    /**
     * 将数据下载到本地
     *
     * @param inputStream 输入流
     * @param path        本地文件路径+文件名 如果不存在则创建
     * @return 下载结果
     */
    public static boolean downloadFile(InputStream inputStream, String path) {
        int bufferSize = switchInputStreamBufferSize(inputStream);
        BufferedOutputStream outputStream = FileUtil.getOutputStream(path);
        long copySize = IoUtil.copy(inputStream, outputStream, bufferSize);
        return copySize > 0;
    }

    /**
     * 下载字符流文件
     *
     * @param reader  字符输入流
     * @param path    本地文件路径+文件名 如果不存在则创建
     * @param charset 字符集
     * @return 操作结果
     */
    public static boolean downloadFile(Reader reader, String path, Charset charset) {
        BufferedWriter bufferedWriter = FileUtil.getWriter(path, charset, false);
        long copySize = IoUtil.copy(reader, bufferedWriter, bufferSize);
        return copySize > 0;
    }

    /**
     * 下载网络文件
     *
     * @param url  网络地址
     * @param path 本地路径+文件名 如果不存在则创建
     * @return 操作结果
     */
    public static boolean downloadFile(String url, String path) {
        InputStream inputStream = null;
        try {
            HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(url).openConnection();
            httpUrlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36)");
            inputStream = httpUrlConnection.getInputStream();
        } catch (IOException e) {
            return false;
        }
        int bufferSize = switchInputStreamBufferSize(inputStream);
        BufferedOutputStream outputStream = FileUtil.getOutputStream(path);
        long copySize = IoUtil.copy(inputStream, outputStream, bufferSize);
        return copySize > 0;
    }

    public static BufferedOutputStream downloadFile(InputStream inputStream) {
        int bufferSize = switchInputStreamBufferSize(inputStream);
        String file = FileUtil.getTmpDirPath() + "$down-tmp.tmp";
        BufferedOutputStream outputStream = FileUtil.getOutputStream(file);
        IoUtil.copy(inputStream, outputStream, bufferSize);
        return outputStream;
    }

    public static BufferedOutputStream downloadFile(String url) {
        InputStream inputStream = null;
        try {
            HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(url).openConnection();
            httpUrlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36)");
            inputStream = httpUrlConnection.getInputStream();
        } catch (IOException e) {
            return null;
        }
        int bufferSize = switchInputStreamBufferSize(inputStream);
        String file = FileUtil.getTmpDirPath() + "$down-tmp.tmp";
        BufferedOutputStream outputStream = FileUtil.getOutputStream(file);
        IoUtil.copy(inputStream, outputStream, bufferSize);
        return outputStream;
    }

    /**
     * 根据文件大小选择不同的缓冲区
     *
     * @param fileSize 文件大小
     * @return 缓存大小
     */
    private static int switchBufferSize(int fileSize) {
//        100M大小
        int mediumSize = 104857600;
//        1G大小
        int maxSize = 1073741824;

        if (fileSize < maxSize && fileSize > mediumSize) {
            bufferSize = IoUtil.DEFAULT_LARGE_BUFFER_SIZE;
        } else if (fileSize > maxSize) {
            bufferSize = IoUtil.DEFAULT_MIDDLE_BUFFER_SIZE;
        }
        return bufferSize;
    }

    private static int switchInputStreamBufferSize(InputStream inputStream) {
        int fileSize = 0;
        try {
            fileSize = inputStream.available();
        } catch (IOException e) {
            throw new RuntimeException("文件大小读取异常");
        }
        return switchBufferSize(fileSize);
    }

}
